<html>
<head><meta charset="utf-8"><title>prototype implementation · t-lang/project-macro-repetition-counts · Zulip Chat Archive</title></head>
<h2>Stream: <a href="https://rust-lang.github.io/zulip_archive/stream/259444-t-lang/project-macro-repetition-counts/index.html">t-lang/project-macro-repetition-counts</a></h2>
<h3>Topic: <a href="https://rust-lang.github.io/zulip_archive/stream/259444-t-lang/project-macro-repetition-counts/topic/prototype.20implementation.html">prototype implementation</a></h3>

<hr>

<base href="https://rust-lang.zulipchat.com">

<head><link href="https://rust-lang.github.io/zulip_archive/style.css" rel="stylesheet"></head>

<a name="221066519"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/259444-t-lang/project-macro-repetition-counts/topic/prototype%20implementation/near/221066519" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mark Juggurnauth-Thomas <a href="https://rust-lang.github.io/zulip_archive/stream/259444-t-lang/project-macro-repetition-counts/topic/prototype.20implementation.html#221066519">(Dec 28 2020 at 15:06)</a>:</h4>
<p>Hi all.  First off, apologies for the long delay with no updates.  I got married in October (hence the name change), and then caught covid in November (all recovered now), so I haven't had much time to work on personal side-projects.</p>
<p>However, I now have a working prototype of declarative macro meta-variable expressions <a href="https://github.com/markbt/rust/commit/04f6cb75445cbf871d8896b178bfb3a437e4916a">available here</a>.  Please try it out and let me know what you think.</p>
<p>There is a test case in that commit that shows off what can be done with the new meta-variable expressions that I have implemented.</p>
<p>I ended up with a couple of changes from the earlier proposals, however I think they make sense.   To summarise them here:</p>
<ul>
<li><code>${count(ident, [depth])}</code> counts the number of repetitions of an identifier at the current repetition depth.  The optional <code>depth</code> parameter allows recursive summation of nested repetitions to a requested depth.</li>
<li><code>${index([depth])</code> returns the index of the current repetition (or if <code>depth</code> is given, the index at that depth from the root).</li>
<li><code>${length([depth])</code> returns the length of the current repetition (or if <code>depth</code> is given, the length at that depth from the root).  <code>index</code> and <code>length</code> are related, in that <code>index</code> will be in the range <code>0..length</code>.</li>
</ul>
<p>I also came up with an addition that may be useful, but it's not completely related, so might need to be deferred to a later RFC:</p>
<ul>
<li><code>${bind(ident)}</code> additionally binds an identifier for reptetion.  This is the same as writing <code>$ident</code> except that it doesn't output the expansion for <code>$ident</code>, but merely binds it for repetition purposes.  This is useful in cases where you want to use <code>${index}</code>, but don't want to emit the expansion.</li>
</ul>
<p>Finally, I ran into some problems with nested macro definitions.  Currently declarative macros attempt to deal with nested definitions by delaying parsing of unrecognised identifiers.  This doesn't really work for meta-variable expressions, for similar reasons that it doesn't work for nested repetitions, where the ambiguity causes issues like <a href="https://github.com/rust-lang/rust/issues/35853">https://github.com/rust-lang/rust/issues/35853</a> .</p>
<p>The solution for both, I believe, is to allow explicit escaping of <code>$</code> when it would otherwise be ambiguous.  Doing this manually by creating an auxillary parameter <code>$d</code>  is the workaround suggested in that issue, so this would formalize that workaround.  It's also trivial to implement, so my changes include allowing <code>$$</code> (which is currently invalid) as an escape for <code>$</code>.  The lazy-parsing remains in place, so it's only really necessary to do this when it would otherwise be ambiguous, so hopefully this allays any concerns that might be had about escaping.</p>
<p>I'm not really sure what the next steps should be.  If this seems like a reasonable approach, perhaps I could start turning this into an RFC document?</p>



<a name="221097505"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/259444-t-lang/project-macro-repetition-counts/topic/prototype%20implementation/near/221097505" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jacob Lifshay <a href="https://rust-lang.github.io/zulip_archive/stream/259444-t-lang/project-macro-repetition-counts/topic/prototype.20implementation.html#221097505">(Dec 28 2020 at 22:52)</a>:</h4>
<p>Could the <code>$</code> escaping be written such that for deeply nested macros you only need N+1 <code>$</code>s to represent the escaped N <code>$</code>s? for example: <code>$$$$var</code> unescapes to <code>$$$var</code> instead of needing 16 <code>$</code>s.</p>



<a name="221124154"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/259444-t-lang/project-macro-repetition-counts/topic/prototype%20implementation/near/221124154" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mark Juggurnauth-Thomas <a href="https://rust-lang.github.io/zulip_archive/stream/259444-t-lang/project-macro-repetition-counts/topic/prototype.20implementation.html#221124154">(Dec 29 2020 at 10:13)</a>:</h4>
<p>The doubling up of the escape characters for each level is necessary so that at each nesting level you can represent a meta-variable whose name is stored in another meta-variable.  An even number of <code>$</code> followed by <code>var</code> (e.g. <code>$$$$var</code>) expands to n/2 <code>$</code>s followed by a literal <code>var</code> (e.g. <code>$$var</code>).  An odd number of <code>$</code> expands to (n-1)/2 <code>$</code>s followed by the expansion of <code>$var</code>, (e.g. if <code>$var == foo</code> then <code>$$$$$var</code> expands to <code>$$foo</code>). </p>
<p>An example of where this would be necessary in existing code is <a href="https://github.com/bluss/defmac/blob/6886f04d412e1ee2b6d4d240feb51e51a9caf808/src/lib.rs#L87">here</a> (linked from the issue I linked).  This code is currently using <code>$dol</code> as a hack for what <code>$$</code> would provide, and <code>$dol $arg</code> would become <code>$$$arg</code>.</p>
<p>Although sixteen <code>$</code> in a row wouldn't be great, quadruply-nested macro definitions are probably not a great idea either, and it should be possible to break the macro down into separate parts with less nesting if that does become a concern.</p>
<p>This part isn't a deal-breaker for this project.  I just hit up against this limitation whilst implementing and testing my prototype, and I think the solution is simple enough that we should also look into it.  I originally thought of providing <code>${dollar}</code> as another meta-variable expression, but when trying it out, that seemed very wordy, and <code>$$</code> looked better.</p>



<a name="221124535"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/259444-t-lang/project-macro-repetition-counts/topic/prototype%20implementation/near/221124535" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jacob Lifshay <a href="https://rust-lang.github.io/zulip_archive/stream/259444-t-lang/project-macro-repetition-counts/topic/prototype.20implementation.html#221124535">(Dec 29 2020 at 10:20)</a>:</h4>
<p>Oh, yeah, I forgot about that.</p>



<a name="223808743"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/259444-t-lang/project-macro-repetition-counts/topic/prototype%20implementation/near/223808743" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mark Juggurnauth-Thomas <a href="https://rust-lang.github.io/zulip_archive/stream/259444-t-lang/project-macro-repetition-counts/topic/prototype.20implementation.html#223808743">(Jan 24 2021 at 11:11)</a>:</h4>
<p>The prototype implementation on this branch: <a href="https://github.com/markbt/rust/tree/metavariable_expressions">https://github.com/markbt/rust/tree/metavariable_expressions</a></p>



<hr><p>Last updated: Aug 07 2021 at 22:04 UTC</p>
</html>